package common

import (
	"encoding/binary"
	"fmt"
	"os"
)

type FileReader struct {
	Path   string
	IsSwap bool
	*os.File
	os.FileInfo
}

func NewFileReader(path string) *FileReader {
	r := new(FileReader)
	r.Path = path
	r.IsSwap = true
	return r
}

func (f *FileReader) Init() (*FileReader, error) {
	file, err := os.Open(f.Path)
	if err != nil {
		fmt.Println(fmt.Sprintf("无法打开文件：%s ", f.Path), err)
		return nil, err
	}
	f.File = file
	f.FileInfo, _ = file.Stat()
	return f, nil
}

func (f *FileReader) ReadUint8() (uint8, error) {
	buffer := make([]byte, 1)
	_, err := f.File.Read(buffer)
	var res uint8 = 0
	if err == nil {
		res = buffer[0]
	}
	return res, err
}

func (f *FileReader) ReadAtUint8(off int64) (uint8, error) {
	buffer := make([]byte, 1)
	_, err := f.File.ReadAt(buffer, off)
	var res uint8 = 0
	if err == nil {
		res = buffer[0]
	}
	return res, err
}

func (f *FileReader) ReadUint16() (uint16, error) {
	buffer := make([]byte, 2)
	_, err := f.File.Read(buffer)
	var res uint16 = 0
	if err == nil {
		res = binary.LittleEndian.Uint16(buffer)
	}
	if f.IsSwap {
		res = Swap16(res)
	}
	return res, err
}

func (f *FileReader) ReadAtUint16(off int64) (uint16, error) {
	buffer := make([]byte, 2)
	_, err := f.File.ReadAt(buffer, off)
	var res uint16 = 0
	if err == nil {
		res = binary.LittleEndian.Uint16(buffer)
	}
	if f.IsSwap {
		res = Swap16(res)
	}
	return res, err
}

func (f *FileReader) ReadUint32() (uint32, error) {
	buffer := make([]byte, 4)
	_, err := f.File.Read(buffer)
	var res uint32 = 0
	if err == nil {
		res = binary.LittleEndian.Uint32(buffer)
	}
	if f.IsSwap {
		res = Swap32(res)
	}
	return res, err
}

func (f *FileReader) ReadAtUint32(off int64) (uint32, error) {
	buffer := make([]byte, 4)
	_, err := f.File.ReadAt(buffer, off)
	var res uint32 = 0
	if err == nil {
		res = binary.LittleEndian.Uint32(buffer)
	}
	if f.IsSwap {
		res = Swap32(res)
	}
	return res, err
}

func (f *FileReader) ReadUint64() (uint64, error) {
	buffer := make([]byte, 8)
	_, err := f.File.Read(buffer)
	var res uint64 = 0
	if err == nil {
		res = binary.LittleEndian.Uint64(buffer)
	}
	if f.IsSwap {
		res = Swap64(res)
	}
	return res, err
}

func (f *FileReader) ReadAtUint64(off int64) (uint64, error) {
	buffer := make([]byte, 8)
	_, err := f.File.ReadAt(buffer, off)
	var res uint64 = 0
	if err == nil {
		res = binary.LittleEndian.Uint64(buffer)
	}
	if f.IsSwap {
		res = Swap64(res)
	}
	return res, err
}

func (f *FileReader) ReadLong() (*Long, error) {
	_uint64, err := f.ReadUint64()
	if err != nil {
		return nil, err
	}
	return NewLong(_uint64), nil
}

func (f *FileReader) ReadAtLong(off int64) (*Long, error) {
	_uint64, err := f.ReadAtUint64(off)
	if err != nil {
		return nil, err
	}
	return NewLong(_uint64), nil
}
